package com.link.base.wechat.wxsubscriber.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.link.base.wechat.wxlog.model.WxLogModule;
import com.link.base.wechat.wxlog.service.WxLogService;
import com.link.base.wechat.wxsubscriber.dao.mybatis.mapper.WxSubscriberMapper;
import com.link.base.wechat.wxsubscriber.model.*;
import com.link.base.wechat.wxsubscriber.util.WxSubscriberUtil;
import com.link.base.wechat.wxtoken.model.WxToken;
import com.link.base.wechat.wxtoken.service.WxTokenService;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.service.BasicServiceImpl;
import com.link.core.basic.service.ServiceException;
import com.link.core.util.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 微信公众号用户管理服务
 *
 * @author ouyangzhenqiang
 * @date 2019/03/01 11:16
 */
@Service
public class WxSubscriberServiceImpl extends BasicServiceImpl<Subscriber> implements WxSubscriberService {
    @Resource
    private WxSubscriberMapper wxSubscriberMapper;
    @Resource
    private WxTokenService wxTokenService;
    @Resource
    private WxLogService wxLogService;

    @Override
    public BasicMapper<Subscriber> getBasicMapper() {
        return wxSubscriberMapper;
    }

    @Override
    public OpenIdList getAllOpenIdList(String wx_app_id) throws Exception {
        Date date = new Date();
        long batchId = date.getTime();
        WxToken wxToken = wxTokenService.getWxAccessTokenByAppId(wx_app_id);
        String access_token = wxToken.getAccess_token();
        OpenIdList openIdList = WxSubscriberUtil.getAllOpenIdList(access_token);
        wxLogService.log(WxLogModule.wxLogUser, "拉取粉丝",
                "【" + batchId + "】本次拉取openId总计 => " + openIdList.getTotal(), wx_app_id, wxToken.getCorpid());
        openIdList.setBatchId(batchId);
        return openIdList;
    }

    @Override
    public SubscriberList getAllSubscriberList(String wx_app_id) throws Exception {
        Date date = new Date();
        long batchId = date.getTime();
        WxToken wxToken = wxTokenService.getWxAccessTokenByAppId(wx_app_id);
        String access_token = wxToken.getAccess_token();
        SubscriberList subscriberList = new SubscriberList();
        OpenIdList openIdList = WxSubscriberUtil.getAllOpenIdList(access_token);
        wxLogService.log(WxLogModule.wxLogUser, "拉取粉丝",
                "【" + batchId + "】本次拉取openId总计 => " + openIdList.getTotal() + "，现在开始拉取粉丝详细数据...", wx_app_id, wxToken.getCorpid());
        int total = openIdList.getOpenList().size();
        subscriberList.setTotal(String.valueOf(total));
        JSONObject result;
        List<Subscriber> list = new ArrayList<>();
        for (int i = 0; i < total; i++) {
            try {
                result = WxSubscriberUtil.getSubscriberInfoByOpenId(access_token, openIdList.getOpenList().get(i));
                list.add(parseSubscriberObj(result));
            } catch (Exception e) {
                wxLogService.error(WxLogModule.wxLogUser, "拉取用户信息",
                        "【" + batchId + "】无法拉取微信用户" + openIdList.getOpenList().get(i) + "的信息 => " + e.getMessage(), wx_app_id, wxToken.getCorpid());
            }
        }
        wxLogService.log(WxLogModule.wxLogUser, "拉取粉丝", "【" + batchId + "】拉取粉丝数据完毕！", wx_app_id, wxToken.getCorpid());
        subscriberList.setList(list);
        subscriberList.setBatchId(batchId);
        return subscriberList;
    }

    @Override
    public SubscriberList getAllSubscriberListNew(String wx_app_id) throws Exception {
        Date date = new Date();
        long batchId = date.getTime();
        WxToken wxToken = wxTokenService.getWxAccessTokenByAppId(wx_app_id);
        String access_token = wxToken.getAccess_token();
        SubscriberList subscriberList = new SubscriberList();
        OpenIdList openIdList = WxSubscriberUtil.getAllOpenIdList(access_token);
        wxLogService.log(WxLogModule.wxLogUser, "拉取粉丝",
                "【" + batchId + "】本次拉取openId总计 => " + openIdList.getTotal() + "，现在开始拉取粉丝详细数据...", wx_app_id, wxToken.getCorpid());
        int total = openIdList.getOpenList().size();
        subscriberList.setTotal(String.valueOf(total));
        JSONObject result;
        List<UserOpenIdList> userOpenIdLists = new ArrayList<>();
        List<OpenIdInfo> openIdInfos = new ArrayList<>();
        List<Subscriber> list = new ArrayList<>();
        for (int i = 0; i < total; i++) {
            OpenIdInfo p = new OpenIdInfo();
            p.setOpenid(openIdList.getOpenList().get(i));
            p.setLang("zh_CN");
            openIdInfos.add(p);
        }
        int toIndex = 100;
        for (int i = 0; i < openIdInfos.size(); i += 100) {
            if (i + 100 > total) {
                toIndex = total - i;
            }
            List<OpenIdInfo> newList = openIdInfos.subList(i,i + toIndex);
            UserOpenIdList userOpenIdList = new UserOpenIdList();
            userOpenIdList.setUser_list(newList);
            userOpenIdLists.add(userOpenIdList);
        }
        for (int i = 0; i < userOpenIdLists.size(); i++) {
            try {
                result = WxSubscriberUtil.getSubscriberInfoListByOpenId(access_token, userOpenIdLists.get(i));
                list.addAll(parseSubscriberObjList(result));
            } catch (Exception e) {
                wxLogService.error(WxLogModule.wxLogUser, "拉取用户信息",
                        "【" + batchId + "】无法拉取微信用户列表" + userOpenIdLists.get(i).toString() + "的信息 => "
                                + e.getMessage(), wx_app_id, wxToken.getCorpid());
            }
        }

        wxLogService.log(WxLogModule.wxLogUser, "拉取粉丝", "【" + batchId + "】拉取粉丝数据完毕！", wx_app_id, wxToken.getCorpid());
        subscriberList.setList(list);
        subscriberList.setBatchId(batchId);
        return subscriberList;
    }

    @Override
    public Subscriber getSubscriberInfoByOpenId(String wx_app_id, String openId) throws Exception {
        WxToken wxToken = wxTokenService.getWxAccessTokenByAppId(wx_app_id);
        String access_token = wxToken.getAccess_token();
        Subscriber subscriber = new Subscriber();
        try {
            JSONObject result = WxSubscriberUtil.getSubscriberInfoByOpenId(access_token, openId);
            subscriber = parseSubscriberObj(result);
        } catch (Exception e) {
            wxLogService.error(WxLogModule.wxLogUser, "拉取用户信息",
                    "无法拉取微信用户【" + openId + "】的信息 => ", wx_app_id, wxToken.getCorpid());
        }
        return subscriber;
    }

    /**
     * 解析用户对象
     *
     * @author 唐健
     * @param obj 用户JSON对象
     * @date 2020/07/02
     */
    private List<Subscriber> parseSubscriberObjList(JSONObject obj) throws Exception {
        Subscriber subscriber = new Subscriber();
        SubscriberList subscriberList = JSONObject.toJavaObject(obj, SubscriberList.class);
        List<Subscriber> list = subscriberList.getUser_info_list();
        for (Subscriber s:list) {
            String subscribe = s.getSubscribe();
            String zero = "0";
            if (zero.equals(subscribe)) {
                throw new ServiceException("WXSUB-001");
            }
        }
        return list;
    }

    /**
     * 解析用户对象
     *
     * @author ouyangzhenqiang
     * @param obj 用户JSON对象
     * @date 2019/03/01 14:23
     */
    private Subscriber parseSubscriberObj(JSONObject obj) throws Exception {
        Subscriber subscriber = new Subscriber();
        String subscribe = obj.getString("subscribe");
        String zero = "0";
        if (zero.equals(subscribe)) {
            throw new ServiceException("WXSUB-001");
        }
        subscriber.setSubscribe(subscribe);
        subscriber.setOpenid(obj.getString("openid"));
        subscriber.setNickname(obj.getString("nickname"));
        subscriber.setSex(obj.getString("sex"));
        subscriber.setLanguage(obj.getString("language"));
        subscriber.setCity(obj.getString("city"));
        subscriber.setProvince(obj.getString("province"));
        subscriber.setCountry(obj.getString("country"));
        subscriber.setHeadimgurl(obj.getString("headimgurl"));
        String subscribe_time = obj.getString("subscribe_time");
        subscriber.setSubscribe_time(subscribe_time);
        subscriber.setUnionid(obj.getString("unionid"));
        subscriber.setRemark(obj.getString("remark"));
        subscriber.setGroupid(obj.getString("groupid"));
        List<String> tagList = new ArrayList<>();
        JSONArray tagArray = obj.getJSONArray("tagid_list");
        for (int i = 0; i < tagArray.size(); i++) {
            tagList.add(tagArray.getString(i));
        }
        subscriber.setTagId_list(tagList);
        subscriber.setSubscribe_scene(obj.getString("subscribe_scene"));
        subscriber.setQr_scene(obj.getString("qr_scene"));
        subscriber.setQr_scene_str(obj.getString("qr_scene_str"));
        return subscriber;
    }

    @Override
    public Subscriber queryByOpenId(String openId) throws Exception {
        if (StringUtils.isBlank(openId)) {
            throw new ServiceException("WXSUB-002");
        }
        Subscriber subscriber = new Subscriber();
        subscriber.setOpenid(openId);
        return wxSubscriberMapper.queryByOpenId(subscriber);
    }

    @Override
    public void insertSub(Subscriber subscriber) throws Exception {
        wxSubscriberMapper.insertSub(subscriber);
    }

    @Override
    public void updateSub(Subscriber subscriber) throws Exception {
        wxSubscriberMapper.updateSub(subscriber);
    }
}
